package com.gateway.video.rtsp.server;

import com.gateway.video.rtsp.server.bootstrap.VideoServerBootstrap;
import com.gateway.video.rtsp.server.channel.DefaultInitChannel;
import com.gateway.video.rtsp.server.channel.InitChannel;
import com.gateway.video.rtsp.server.config.VideoServerConfig;
import com.gateway.video.rtsp.server.handler.RtspServerHandler;
import com.gateway.video.rtsp.server.transport.rtp.bootstrap.RtpServerBootstrap;
import com.gateway.video.rtsp.server.transport.rtp.handler.RtpServerHandler;
import com.gateway.video.rtsp.server.transport.rtcp.bootstrap.RtcpServerBootstrap;
import com.gateway.video.rtsp.server.transport.rtcp.handler.RtcpServerHandler;
import com.gateway.video.rtsp.server.util.ApplicationContextUtil;
import com.gateway.video.rtsp.stream.h264.H264VideoStream;
import com.gateway.video.rtsp.stream.pull.PullStart;
import com.gateway.video.rtsp.stream.pull.PullVideoConfig;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.var;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

@EnableConfigurationProperties({VideoServerConfig.class, PullVideoConfig.class})
public class VideoServerConfiguration {
    @Bean
    public VideoServerBootstrap videoServerBootstrap() {
        return new VideoServerBootstrap();
    }

    @Bean
    public InitChannel initChannel() {
        return new DefaultInitChannel();
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RtspServerHandler rtspServerHandler() {
        return new RtspServerHandler();
    }

    @Bean
    public EventLoopGroup eventLoopGroup() {
        return new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("video-rtsp-server-worker-pool-%s").build());
    }

    @Bean
    public Gson gson() {
        return new GsonBuilder().create();
    }

    @Bean
    public ApplicationContextUtil applicationContextUtil() {
        return new ApplicationContextUtil();
    }

    /*------------------------------------------------------------- RDP -------------------------------------------------------------*/
    @Bean
    public RtpServerBootstrap rdpServerBootstrap() {
        var group = new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("video-rdp-server-worker-pool-%s").build());
        return new RtpServerBootstrap(group);
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RtpServerHandler rdpServerHandler() {
        return new RtpServerHandler();
    }

    /*------------------------------------------------------------- RTCP -------------------------------------------------------------*/
    @Bean
    public RtcpServerBootstrap rtcpServerBootstrap() {
        var group = new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("video-rtcp-server-worker-pool-%s").build());
        return new RtcpServerBootstrap(group);
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RtcpServerHandler rtcpServerHandler() {
        return new RtcpServerHandler();
    }

    /*------------------------------------------------------------- STREAM -------------------------------------------------------------*/
    @Bean
    public PullStart pullStart(PullVideoConfig pullVideoConfig) {
        return new PullStart(pullVideoConfig);
    }

    @Bean
    public H264VideoStream h264VideoStream() {
        return new H264VideoStream();
    }
}
